import * as React from 'react';
import { Button, message, Icon, Upload, notification } from 'antd';
import { API_ROOT } from 'config/app';
import CONFIG from 'constants/config';
import CustomModal from './CustomModal';

interface UploadBasicProps {
  onSelected?: (url: string) => void;
  onLoading?: (args1: any, args2: any) => void;
  multiple?: boolean;
  target?: any;
  listType?: any;
  type?: string;
}

interface UploadBasicState {
  uploadStatus: any;
  previewImageUrl: string;
  previewVisible: boolean;
}

const medias: any = {
  image: {
    accept: CONFIG.IMAGE_ACCEPT,
    maxSize: CONFIG.IMAGE_MAXSIZE,
    type: 0,
  },
  audio: {
    accept: CONFIG.AUDIO_ACCEPT,
    maxSize: CONFIG.AUDIO_MAXSIZE,
    type: 1,
  },
  video: {
    accept: CONFIG.VIDEO_ACCEPT,
    maxSize: CONFIG.VIDEO_MAXSIZE,
    type: 2,
  },
};

function getMediaAttr(target: any, attrName: string) {
  if (!medias[target] || !medias[target][attrName]) return null;
  return medias[target][attrName];
}

class UploadBasic extends React.Component<UploadBasicProps, UploadBasicState> {
  maxSize: number;
  target: string;
  accept: string;
  serviceType: number;
  static defaultProps: UploadBasicProps = {
    onSelected: () => {},
    onLoading: () => {},
    multiple: true,
    target: null,
    listType: 'picture-card',
    type: 'text',
  };
  constructor(props: UploadBasicProps) {
    super(props);

    this.state = {
      uploadStatus: null,
      previewImageUrl: '',
      previewVisible: false,
    };

    // 没有限制附件类型的话根据用户上传文件类型判断
    if (props.target) {
      this.initParams(props.target);
    }
  }

  initParams(target: string) {
    this.target = target;
    this.maxSize = getMediaAttr(this.target, 'maxSize');
    this.accept = getMediaAttr(this.target, 'accept');
    this.serviceType = getMediaAttr(this.target, 'type');
  }

  isDone() {
    return this.state.uploadStatus === 'done';
  }

  isUploading() {
    return this.state.uploadStatus === 'uploading';
  }

  isError() {
    return this.state.uploadStatus === 'error';
  }

  handleChange = (info: any) => {
    const { onSelected, onLoading } = this.props;
    const { file } = info;

    this.setState(
      {
        uploadStatus: file.status,
      },
      () => {
        if (this.isUploading()) {
          if (onLoading && typeof onLoading !== undefined) {
            onLoading(file.name, file.percent);
          }
        } else if (this.isDone()) {
          if (file.response && file.response.code === 0) {
            notification.success({
              message: 'Success',
              description: `[${file.name}] 上传成功`,
              duration: 2,
            });

            if (onSelected && typeof onSelected === 'function') {
              onSelected(file.response.data);
            }
          } else {
            notification.success({
              message: 'Error',
              description: `[${file.name}] 上传失败`,
              duration: 3,
            });
          }
        } else if (this.isError()) {
          notification.error({
            message: 'Error',
            description: `[${file.name}] 上传失败`,
            duration: 3,
          });
        }
      }
    );
  };

  handleBeforeUpload = (file: any) => {
    // 不管有没有指定文件类型的都得检查是否符合规范，
    // 因为上传的时候可以选择所有文件类型，从而绕过限制
    const type = file.type.toLowerCase();
    if (medias.image.accept.indexOf(type) !== -1) {
      this.initParams('image');
    } else if (medias.audio.accept.indexOf(type) !== -1) {
      this.initParams('audio');
    } else if (medias.video.accept.indexOf(type) !== -1) {
      this.initParams('video');
    } else {
      message.error(`不支持的文件类型[${type}]`);
      return false;
    }

    return new Promise((resolve: any, reject: any) => {
      if (file.size > this.maxSize * 1024 * 1024) {
        message.error(`超出最大${this.maxSize}M的限制`);
        reject(file);
      }

      resolve(file);
    });
  };

  handlePreview = (file: any) => {
    const url = file.url ? file.url : file.thumbUrl;

    this.setState({
      previewImageUrl: url,
      previewVisible: true,
    });
  };

  handleCancel = () => {
    this.setState({
      previewVisible: false,
    });
  };

  render() {
    const { previewImageUrl, previewVisible } = this.state;
    const { multiple, listType, type } = this.props;

    const action = `${API_ROOT}/course-api/a/attachments`;
    // const headers = {
    //   'X-Requested-With': null,
    //   /*Authorization: `Bearer ${auth.getAccessToken()}`,*/
    // };

    let children = null;
    if (type && type === 'onlyText') {
      children = (
        <React.Fragment>
          <Icon type={this.isUploading() ? 'loading' : 'upload'} />
          上传
        </React.Fragment>
      );
    } else if (listType === 'text') {
      children = (
        <Button>
          <Icon type={this.isUploading() ? 'loading' : 'upload'} /> 上传
        </Button>
      );
    } else {
      children = (
        <div>
          <Icon type={this.isUploading() ? 'loading' : 'plus'} />
          <div className="ant-upload-text">上传</div>
        </div>
      );
    }

    return (
      <div className="clearfix">
        <Upload
          data={() => {
            return { type: this.serviceType };
          }}
          action={action}
          multiple={multiple}
          showUploadList={false}
          accept={this.accept}
          listType={listType}
          disabled={this.isUploading()}
          beforeUpload={this.handleBeforeUpload}
          onPreview={this.handlePreview}
          onChange={this.handleChange}>
          {children}
        </Upload>
        <CustomModal visible={previewVisible} onCancel={this.handleCancel}>
          <img alt="preview" style={{ width: '100%' }} src={previewImageUrl} />
        </CustomModal>
      </div>
    );
  }
}

export default UploadBasic;
